using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.Package;
using Microsoft.WowAddonStudio.Lua.LanguageService.Model;
using Microsoft.WowAddonStudio.Lua.Model;

namespace Microsoft.WowAddonStudio.Lua.LanguageService.Intellisense
{
    public abstract class DeclarationProvider : IDeclarationProvider
    {
        protected LuaParseRequest Request { get; private set; }

        /// <summary>
        /// Initializes the declaration provider.
        /// </summary>
        /// <param name="parseRequest"></param>
        public void Initialize(LuaParseRequest parseRequest)
        {
            if (parseRequest == null)
                throw new ArgumentNullException("parseRequest");
            if (parseRequest.Sink.GetType() != typeof(LuaAuthoringSink))
                throw new ArgumentException("Parse request must use LuaAuthoringSink.s");

            this.Request = parseRequest;
            this.Initialize();
        }

        protected virtual void Initialize()
        {
        }

        /// <summary>
        /// Gets the declarations provided.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Declaration> GetDeclarations()
        {
            if (Request.Reason == ParseReason.CompleteWord ||
                Request.Reason == ParseReason.DisplayMemberList)
                return this.GetWords();

            if (Request.Reason == ParseReason.MemberSelect)
                return this.GetMembers();

            return new Declaration[0];
        }

        protected virtual IEnumerable<Declaration> GetWords()
        {
            return new Declaration[0];
        }

        protected virtual IEnumerable<Declaration> GetMembers()
        {
            return new Declaration[0];
        }

        /// <summary>
        /// Gets the methods.
        /// </summary>
        /// <returns>
        /// An enumerable collection of <see cref="Function"/> instances.
        /// </returns>
        public virtual IEnumerable<Function> GetMethods()
        {
            return new Function[0];
        }

        /// <summary>
        /// Gets a data tip.
        /// </summary>
        /// <returns>
        /// An instance of the <see cref="DataTip"/> class or null if no data tip can be provided.
        /// </returns>
        public virtual DataTip GetDataTip()
        {
            return null;
        }

        /// <summary>
        /// Gets the source of the declaration.
        /// </summary>
        /// <returns>
        /// An instance of the <see cref="DeclarationSource"/> class or null if no declaration source can be provided.
        /// </returns>
        public virtual DeclarationSource GetDeclarationSource()
        {
            return null;
        }

        /// <summary>
        /// Gets the authoring sink associated with the request and the declaration provider.
        /// </summary>
        protected LuaAuthoringSink AuthoringSink
        {
            get { return (LuaAuthoringSink)Request.Sink; }
        }
    }
}